package com.project.aiqicha;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.project.frame.common.model.BaseResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * desc
 *
 * @author cjq
 * @date 2023-08-31
 */
@Service
@Slf4j
public class AiqichaService {

    String errMsg = "企业查询服务已暂时关闭，请向技术人员反馈开启[D]";

    String reg = "(?<=window.pageData=).*(?=;window.isSpider)";


    public BaseResp search(String name,String code){
        BaseResp resp = new BaseResp();
        Map<String,String> headerMap = new HashMap<>();
        String cookie = getCookie();
        headerMap.put("Cookie",cookie);

        String url = "https://aiqicha.baidu.com/s";
        if(StrUtil.isNotEmpty(code)){
            url+="?q="+code;
        }else {
            url+="?q="+name;
        }
        HttpResponse res = HttpUtil.createGet(url).headerMap(headerMap,true).execute();
        int status = res.getStatus();
        if(res.isOk()){
            String body = res.body();
            if(!body.contains("window.pageData")){
                return BaseResp.renderFail(AiqichaCode.CODE_NO_PAGE_DATA,"企业查询服务页面无数据，请向技术人员反馈");
            }
            //(?<=window.pageData=).*(?=;window.isSpider)

            body = body.replaceAll("[ \t\n\r]","");
            String pageDataStr =  ReUtil.getGroup0(reg,body);

            resp = getMathItem(pageDataStr,name,code);
            if(resp.isSuccess()==false){
                return resp;
            }

            JSONObject item = (JSONObject)resp.getData();
            resp = getEnterpriseInfoBySearchItem(item);
            Map<String,Object> entMap = (Map<String,Object>)resp.getData();

            String pid = item.getString("pid");
            resp = GetEnterpriseInfoBySearchDetail(pid,entMap);
            if(resp.isSuccess()==false){
                return resp;
            }
            entMap = (Map<String,Object>)resp.getData();

            resp = GetBasicAllData(pid,entMap);
            if(resp.isSuccess()==false){
                return resp;
            }

            resp = 获取企业异常信息(entMap, pid);
            if(resp.isSuccess() == false)
            {
                return resp;
            }
            if(entMap.get("BelongHeadOffice")==null){
                entMap.put("BelongHeadOffice",new HashMap<>());
            }

            return BaseResp.renderSuccess(entMap);
        }else{
            if(status==302){
                //return BaseResp.renderFail(AiqichaCode.CODE_302,"#企业查询服务已暂时关闭，请向技术人员反馈开启");
                return BaseResp.renderFail(AiqichaCode.CODE_302,"#客户名称或者税号不正确，请完善后重试");
            }
            log.info("status="+status+",body="+res.body());
            return BaseResp.renderFail(AiqichaCode.CODE_FAIL,"企业查询服务查询失败，失败状态码："+status);
        }
    }

    private BaseResp 获取企业异常信息(Map<String, Object> entMap, String pid) {
        String url = "https://aiqicha.baidu.com/detail/focalPointAjax?pid=" + pid;
        Map<String,String> headerMap = new HashMap<>();
        String cookie = getCookie();
        headerMap.put("Cookie",cookie);
        headerMap.put("Referer","https://aiqicha.baidu.com/company_detail_"+pid+"?tab=risk");
        HttpResponse res = HttpUtil.createGet(url).headerMap(headerMap,true).execute();
        if(res.isOk()==false){
            return BaseResp.renderFail(-14,errMsg);
        }
        String body = res.body();
        if (body.contains("百度安全验证")){
            return BaseResp.renderFail(-15,errMsg);
        }

        JSONObject respObj = JSONObject.parseObject(body);
        JSONObject dataObj = respObj.getJSONObject("data") ;
        JSONObject abnormalObj = dataObj.getJSONObject("abnormal");
        JSONArray abnormalList = abnormalObj.getJSONArray("list") ;
        entMap.put("AbnormalInfo","");
        entMap.put("AbnormalDate","1900-1-1");
        if (abnormalList!=null && abnormalList.size() > 0)
        {
            JSONObject abnormalItem = abnormalList.getJSONObject(0);
            entMap.put("AbnormalInfo",abnormalItem.getString("leaveReason"));
            String enterDateStr = abnormalItem.getString("enterDate") ;
            if(!StrUtil.isEmpty(enterDateStr) && !enterDateStr.equals("-"))
            {
                entMap.put("AbnormalDate",enterDateStr);
            }
        }

        return BaseResp.renderSuccess(entMap);
    }

    private BaseResp GetBasicAllData(String pid, Map<String, Object> entMap) {

        BaseResp resp = GetBasicAllDataAjax(pid);
        if(resp.isSuccess()==false){
            return resp;
        }
        JSONObject dataObj = (JSONObject)resp.getData();
        JSONObject annualReportData = dataObj.getJSONObject("annualReportData");
        int annualReportDataTotal = annualReportData.getInteger("total");
        if(annualReportDataTotal>0){
            JSONArray reportYears = annualReportData.getJSONArray("reportYears");
            if(reportYears!=null && reportYears.size()>0){
                String reportYear = reportYears.getString(0);
                String RecentInspectionDate = reportYear + "-01-01";
                entMap.put("RecentInspectionDate",RecentInspectionDate);
            }else{
                entMap.put("RecentInspectionDate","1900-1-1");
            }
        }

        JSONObject shareholdersData= dataObj.getJSONObject("shareholdersData");
        JSONArray shareholdersList = shareholdersData.getJSONArray("list");

        List<Map<String,Object>> InvestorList = new ArrayList<>();

        if(shareholdersList!=null && shareholdersList.size()>0){
            for (int i = 0; i < shareholdersList.size(); i++) {
                Map<String,Object> 股东Map = new HashMap<>();

                JSONObject shareholderItem = shareholdersList.getJSONObject(i);
                String 股东或合伙人名称 = shareholderItem.getString("name");
                股东Map.put("股东或合伙人名称",股东或合伙人名称);

                String personId = shareholderItem.getString("personId");
                String stockId = shareholderItem.getString("stockId");
                if(StrUtil.isEmpty(personId)){
                    personId = stockId;
                }
                String nowType = shareholderItem.getString("nowType");

                resp = Get出资信息(股东Map,pid,personId,nowType,股东或合伙人名称);
                if(resp.isSuccess()==false){
                    return resp;
                }
                InvestorList.add(股东Map);
            }
        }

        entMap.put("InvestorList",InvestorList);

        JSONObject basicDataObj = dataObj.getJSONObject("basicData");
        String openTimeStr= basicDataObj.getString("openTime");
        if(StrUtil.isNotEmpty(openTimeStr) && !"-".equals(openTimeStr)){
            String[] openTimeArr = openTimeStr.split(" 至 ");
            if(openTimeArr.length>1){
                if (openTimeArr[1].contains("无固定期限"))
                {
                    entMap.put("CloseDate","2999-1-1");
                }
                else
                {
                    entMap.put("CloseDate",openTimeArr[1]);
                }
                entMap.put("OpenDate",openTimeArr[0]);
            }
        }

        resp = GetOutwardInvestmentList(entMap,pid);
        if(resp.isSuccess()==false){
            return resp;
        }

        JSONObject headCompanyObj = dataObj.getJSONObject("headCompany");
        if(headCompanyObj!=null && headCompanyObj.size()>0){
            JSONArray list = headCompanyObj.getJSONArray("list");
            if(list!=null && list.size()>0){
                JSONObject item0 = list.getJSONObject(0);
                String 总机构名称 = item0.getString("entName");
                Map<String,Object> 总机构Map = new HashMap<>();
                总机构Map.put("总机构名称",总机构名称);

                String entUrl = item0.getString("entUrl");

                resp = GetTaxNoByLink(entUrl);
                if(resp.isSuccess()==false){
                    return resp;
                }

                JSONObject taxObj = (JSONObject)resp.getData();
                String taxNo = taxObj.getString("taxNo");
                String licenseNumber = taxObj.getString("licenseNumber");
                // 总机构.总机构统一社会信用代码 = taxNo;
                //                总机构.总机构注册号 = licenseNumber;
                总机构Map.put("总机构统一社会信用代码",taxNo);
                总机构Map.put("总机构注册号",licenseNumber);

                entMap.put("BelongHeadOffice",总机构Map);
            }
        }

        return BaseResp.renderSuccess(entMap);
    }

    private BaseResp GetTaxNoByLink(String entUrl) {
        String url = "https://aiqicha.baidu.com" + entUrl;
        Map<String,String> headerMap = new HashMap<>();
        String cookie = getCookie();
        headerMap.put("Cookie",cookie);

        HttpResponse res = HttpUtil.createGet(url).headerMap(headerMap,true).execute();
        if (res.isOk() == false) {

            return BaseResp.renderFail(-11,errMsg);
        }
        String body = res.body();
        if (!body.contains("window.pageData") || body.contains("百度安全验证")){
            return BaseResp.renderFail(-12,errMsg);
        }
        body = body.replaceAll("\n", "").replaceAll(" ", "").replaceAll("\t", "").replaceAll("\r", "");
        String pageData = ReUtil.getGroup0(reg,body);
        if (StrUtil.isEmpty(pageData))
        {
            return BaseResp.renderFail(-13,errMsg);
        }
        JSONObject pageDataObj = JSONObject.parseObject(pageData);
        JSONObject resultObj = pageDataObj.getJSONObject("result") ;

        String taxNo = resultObj.getString("taxNo");
        String licenseNumber = resultObj.getString("licenseNumber");
        JSONObject returnObj = new JSONObject();
        returnObj.put("taxNo", taxNo);
        returnObj.put("licenseNumber", licenseNumber);

        return BaseResp.renderSuccess(returnObj);
    }

    private BaseResp GetOutwardInvestmentList(Map<String, Object> entMap, String pid) {

        BaseResp resp = new BaseResp();

        List<Map<String,Object>> OutwardInvestmentList = new ArrayList<>();
        try{
            String url = "https://aiqicha.baidu.com/detail/investajax?p=1&size=40&pid=" + pid;
            Map<String,String> headerMap = new HashMap<>();
            String cookie = getCookie();
            headerMap.put("Cookie",cookie);
            headerMap.put("Referer","https://aiqicha.baidu.com/company_detail_"+pid+"?tab=basic");
            HttpResponse res = HttpUtil.createGet(url).headerMap(headerMap,true).execute();

            if(res.isOk()==false){
                return BaseResp.renderFail(-9,errMsg);
            }
            String body = res.body();
            if(body.contains("百度安全验证")){
                return BaseResp.renderFail(-10,errMsg);
            }

            JSONObject respObj = JSONObject.parseObject(body);

            JSONObject dataObj = respObj.getJSONObject("data");
            JSONArray list = dataObj.getJSONArray("list");
            if(list!=null && list.size()> 0)
            {
                for(int i=0;i<list.size();i++)
                {
                    JSONObject item = list.getJSONObject(i);
                    Map<String,Object> 对外投资 = new HashMap<>();
                    String entName =item.getString("entName");
                    对外投资.put("投资设立企业或购买股权企业名称",entName);
                    对外投资.put("企业状态",item.getString("openStatus"));

                    String entLink = item.getString("entLink");

                    resp = GetTaxNoByLink( entLink);
                    if (resp.isSuccess() == false)
                    {
                        return resp;
                    }
                    JSONObject taxObj = (JSONObject)resp.getData();
                    String taxNo = taxObj.getString("taxNo") ;
                    对外投资.put("统一社会信用代码或注册号",taxNo);

                    OutwardInvestmentList.add(对外投资);
                }
            }
        }catch(Exception e){
            if(e.getMessage().contains("Unexpected end of file from server")){

            }else{
                return BaseResp.renderFail(-15,"对外投资获取异常");
            }
        }
        entMap.put("OutwardInvestmentList",OutwardInvestmentList);
        return BaseResp.renderSuccess(entMap);
    }

    private BaseResp Get出资信息(Map<String, Object> 股东Map,String pid, String personId, String nowType, String name) {

        String url = "https://aiqicha.baidu.com/detail/getStockDetailAjax?pid=" + pid;
        url += "&isPublic=" + nowType + "&id=" + personId + "&name=" + name;
        Map<String,String> headerMap = new HashMap<>();
        String cookie = getCookie();
        headerMap.put("Cookie",cookie);
        headerMap.put("Referer","https://aiqicha.baidu.com/company_detail_"+pid+"?tab=basic");

        HttpResponse res = HttpUtil.createGet(url).headerMap(headerMap,true).execute();

        if(res.isOk()==true){
            String body = res.body();
            if(body.contains("百度安全验证")){
                return BaseResp.renderFail(-16,errMsg);
            }
            JSONObject respObj = JSONObject.parseObject(body);
            int status = respObj.getInteger("status");
            if(status!=0){
                return BaseResp.renderFail(-17,errMsg);
            }
            JSONObject dataObj = respObj.getJSONObject("data");

            Map<String,Object> 认缴出资信息 = new HashMap<>();
            认缴出资信息.put("资本币种","人民币");
            认缴出资信息.put("出资方式","货币");
            认缴出资信息.put("出资时间或期限","1900-1-1");
            认缴出资信息.put("出资比例",0);
            认缴出资信息.put("出资额",0);

            Map<String,Object> 实缴出资信息 = new HashMap<>();
            实缴出资信息.put("资本币种","人民币");
            实缴出资信息.put("出资方式","货币");
            实缴出资信息.put("出资时间或期限","1900-1-1");
            实缴出资信息.put("出资比例",0);
            实缴出资信息.put("出资额",0);

            JSONObject moneyObj = dataObj.getJSONObject("money");
            JSONArray paidinDataArr = moneyObj.getJSONArray("paidinData");

            if(paidinDataArr!=null && paidinDataArr.size()>0){
                JSONObject paidinData=paidinDataArr.getJSONObject(0);
                String paidinMoney = paidinData.getString("paidinMoney");
                if (StrUtil.isNotEmpty(paidinMoney)&& !paidinMoney.equals("-"))
                {
                    if (paidinMoney.contains("万(元)") || paidinMoney.contains("万"))
                    {
                        double 出资额 = Double.parseDouble(paidinMoney.replaceAll("万\\(元\\)", "").replaceAll(",", "").replaceAll("万", ""));
                        出资额 = 出资额 * 10000;
                        实缴出资信息.put("出资额",出资额);
                    }
                    else
                    {
                        double 出资额 = Double.parseDouble(paidinMoney.replaceAll("\\(元\\)", "").replaceAll(",", "").replaceAll("元", ""));
                        实缴出资信息.put("出资额",出资额);
                    }
                    String paidinTimeStr = paidinData.getString("paidinTime");
                    if (StrUtil.isNotEmpty(paidinTimeStr) && !paidinTimeStr.equals("-"))
                    {
                        实缴出资信息.put("出资时间或期限",paidinTimeStr);
                    }
                }
            }

            JSONArray subDataArr  = moneyObj.getJSONArray("subData");
            if(subDataArr != null && subDataArr.size() > 0)
            {
                JSONObject subData = subDataArr.getJSONObject(0);
                String subMoney = subData.getString("subMoney");
                if (StrUtil.isNotEmpty(subMoney) && !subMoney.equals("-"))
                {
                    if (subMoney.contains("万(元)") || subMoney.contains("万"))
                    {
                        double 出资额 = Double.parseDouble(subMoney.replaceAll("万\\(元\\)", "").replaceAll(",", "").replaceAll("万", ""));
                        出资额 = 出资额 * 10000;
                        实缴出资信息.put("出资额",出资额);
                    }
                    else
                    {
                        double 出资额 = Double.parseDouble(subMoney.replaceAll("\\(元\\)", "").replaceAll(",", "").replaceAll("元", ""));
                        实缴出资信息.put("出资额",出资额);
                    }
                    String subTimeStr = subData.getString("subTime");
                    if(StrUtil.isNotEmpty(subTimeStr) && !subTimeStr.equals("-"))
                    {
                        实缴出资信息.put("出资时间或期限",subTimeStr);
                    }

                }
            }

            JSONObject basicObj =dataObj.getJSONObject("basic") ;
            String subRateStr = basicObj.getString("subRate");
            if(StrUtil.isEmpty(subRateStr) || subRateStr.equals("-"))
            {
                认缴出资信息.put("出资比例",0);
            }
            else
            {
                double subRate = Double.parseDouble(subRateStr.replaceAll("%", ""));
                认缴出资信息.put("出资比例",NumberUtil.round(subRate/100,7));
//                认缴出资信息.出资比例 = Math.round(subRate / 100, 7);
            }
            实缴出资信息.put("出资比例",认缴出资信息.get("出资比例"));

            股东Map.put("认缴出资信息",认缴出资信息);
            股东Map.put("实缴出资信息",实缴出资信息);

            //

            return BaseResp.renderSuccess(股东Map);
        }
        return BaseResp.renderFail(-18,errMsg);
    }

    private BaseResp GetBasicAllDataAjax(String pid) {
        Map<String,String> headerMap = new HashMap<>();

        try{
            String cookie = getCookie();
            headerMap.put("Cookie",cookie);
            headerMap.put("Referer","https://aiqicha.baidu.com/company_detail_"+pid+"?tab=basic");
            String url = "https://aiqicha.baidu.com/detail/basicAllDataAjax?pid=" + pid;
            HttpResponse res = HttpUtil.createGet(url).headerMap(headerMap,true).execute();
            if(res.isOk()==true){
                String body = res.body();
                if(body.contains("百度安全验证")){
                    return BaseResp.renderFail(-6,errMsg);
                }
                JSONObject bodyObj = JSONObject.parseObject(body);
                JSONObject dataObj = bodyObj.getJSONObject("data");

                return BaseResp.renderSuccess(dataObj);
            }
        }catch(Exception e){
            return BaseResp.renderFail(-7,errMsg);
        }
        return BaseResp.renderFail(-8,errMsg);
    }

    private BaseResp GetEnterpriseInfoBySearchDetail(String pid, Map<String, Object> entMap) {
        String url = "https://aiqicha.baidu.com/company_detail_" + pid;

        Map<String,String> headerMap = new HashMap<>();
        String cookie = getCookie();
        headerMap.put("Cookie",cookie);

        try{
            HttpResponse res = HttpUtil.createGet(url).headerMap(headerMap,true).execute();
            if(res.isOk()==true){
                String body = res.body();
                if(!body.contains("window.pageData")){
                    return BaseResp.renderFail(-3,errMsg);
                }

                body = body.replaceAll("[ \t\n\r]","");
                String pageDataStr =  ReUtil.getGroup0(reg,body);
                JSONObject pageDataObj = JSONObject.parseObject(pageDataStr);
                JSONObject resultObj = pageDataObj.getJSONObject("result");
                String regAddr = resultObj.getString("regAddr");
                String addr = resultObj.getString("addr");
                String startDate = resultObj.getString("startDate");
                if(StrUtil.isNotEmpty(startDate) && !"-".equals(startDate)){
                    entMap.put("RegisteredDate",startDate);
                    entMap.put("OpenDate",startDate);
                }
                String telephone = resultObj.getString("telephone");

                entMap.put("RegisteredAddress",regAddr);
                entMap.put("BusinessAddress",addr);

                entMap.put("RecordPersonPhone",telephone);
                entMap.put("RecordPersonName","");
                return BaseResp.renderSuccess(entMap);
            }else{
                return BaseResp.renderFail(-4,errMsg);
            }
        }catch(Exception e){
            return BaseResp.renderFail(-5,errMsg);
        }
    }

    private BaseResp getEnterpriseInfoBySearchItem(JSONObject item) {
        String regNo = item.getString("regNo");
        String titleName = item.getString("titleName");
        String openStatus = item.getString("openStatus");
        String domicile = item.getString("domicile");
        String legalPerson = item.getString("legalPerson");
        String regCap = item.getString("regCap");

        regCap = regCap.replace(",", "");
        String CapitalUnit = "元人民币";
        double RegisteredCapital = 0;
        if (regCap.contains("万(元)"))
        {
            CapitalUnit = "万元人民币";
            regCap = regCap.replace("万(元)", "");
            RegisteredCapital = Double.parseDouble(regCap) ;
        }
        else if (regCap.contains("万"))
        {
            CapitalUnit = "万元人民币";
            regCap = regCap.replace("万", "");
            RegisteredCapital = Double.parseDouble(regCap) ;
        }
        else if (regCap.contains("(元)"))
        {
            CapitalUnit = "元人民币";
            regCap = regCap.replace("(元)", "");
            RegisteredCapital = Double.parseDouble(regCap);
        }

        String scope = item.getString("scope");
        String validityFrom = item.getString("validityFrom");
        String entType = item.getString("entType");

        Map<String,Object> enterpriseInfoMap = new HashMap<>();
        enterpriseInfoMap.put("EnterpriseID",regNo);
        enterpriseInfoMap.put("EnterpriseName",titleName);
        enterpriseInfoMap.put("EnterpriseStatus",openStatus);
        enterpriseInfoMap.put("BusinessLicenceNumber",regNo);
        enterpriseInfoMap.put("RegisteredAddress",domicile);
        enterpriseInfoMap.put("BusinessAddress",domicile);
        enterpriseInfoMap.put("CorporateRepresentative",legalPerson);
        enterpriseInfoMap.put("RegisteredCapital",RegisteredCapital);
        enterpriseInfoMap.put("CapitalUnit",CapitalUnit);
        enterpriseInfoMap.put("PaidupCapital",0);
        enterpriseInfoMap.put("BusinessScope",scope);
        enterpriseInfoMap.put("RegisteredDate",validityFrom);
        enterpriseInfoMap.put("EnterpriseType",entType);

        return BaseResp.renderSuccess(enterpriseInfoMap);

    }

    private BaseResp getMathItem(String pageDataStr, String name, String code) {
        JSONObject pageDataObj = JSONObject.parseObject(pageDataStr);
        JSONObject resultObj = pageDataObj.getJSONObject("result");
//        resultObj.getJSONArray()//totalNumFound
        int totalNumFound = resultObj.getInteger("totalNumFound");
        if(totalNumFound<=0){
            return BaseResp.renderFail("未查到数据");
        }
        JSONArray resultList = resultObj.getJSONArray("resultList");
        for (int i = 0; i < resultList.size(); i++) {
            JSONObject rec = resultList.getJSONObject(i);
            List<String> entNameList = new ArrayList<>();
            String regNo = rec.getString("regNo");
            String titleName = rec.getString("titleName");
            String entName = rec.getString("entName");
            entName = entName.replaceAll("<em>", "").replaceAll("</em>", "");
//福州市仓山区黄英灿营销策划服务部（个体工商户）
            String replaceTxt = "（个体工商户）";
            if(titleName.contains(replaceTxt)){
                titleName = titleName.replace(replaceTxt,"");
            }
            if(entName.contains(replaceTxt)){
                entName = entName.replace(replaceTxt,"");
            }
            entNameList.add(titleName);
            entNameList.add(entName);
            if(rec.toJSONString().contains("曾用名")){
                List<String> preNameList = getPreName(rec);
                if(preNameList!=null && preNameList.size()>0){
                    entNameList.addAll(preNameList);
                }
            }

            if(StrUtil.isNotEmpty(code)){
                if(code.equals(regNo)){
                    return BaseResp.renderSuccess(rec);
                }
            }else{
                if(entNameList.contains(name)){
                    return BaseResp.renderSuccess(rec);
                }
            }

        }
        return BaseResp.renderFail("结果数据不存在");
    }

    private List<String> getPreName(JSONObject rec) {
        List<String> preNameList = new ArrayList<>();
        JSONArray newLabels = rec.getJSONArray("newLabels");
        for (int i = 0; i < newLabels.size(); i++) {
            JSONObject obj = newLabels.getJSONObject(i);
            String key = obj.getString("key");
            if("formernames".equals(key)){
                JSONObject valueObj = obj.getJSONObject("value");
                JSONArray names = valueObj.getJSONArray("names");
                for (int j = 0; j < names.size(); j++) {
                    preNameList.add(names.getString(j));
                }
                break;
            }
        }
        return preNameList;
    }

    public String getCookie() {
        ClassPathResource classPathResource = new ClassPathResource("cookie.txt");
        String ck = FileUtil.readString(classPathResource.getAbsolutePath(), CharsetUtil.CHARSET_UTF_8);
        return ck;
    }

}
